import Empty from 'components/Empty';
import {ToastManger} from 'components/Toast';
import {BGList} from 'components/View/BackGround';
import React, {useCallback, useEffect, useState} from 'react';
import {
  ActivityIndicator,
  FlatListProps,
  RefreshControl,
  Text,
} from 'react-native';
import {STYLE_COLOR} from 'variables';

export interface DataListProps<T> extends Omit<FlatListProps<T>, 'data'> {
  api: (...idx: any[]) => Promise<T[]>;
  type: 'id' | 'offset';
}

export function DataList<T>({
  api,
  renderItem,
  ListHeaderComponent,
}: DataListProps<T>) {
  /** 初始化，能否追加，正在追加，正在刷新， */
  const [data, setData] = useState<T[] | undefined>();
  const [canAppend, setCanAppend] = useState(false);

  const [init, setInit] = useState(false);
  const [appending, setAppendIng] = useState(false);
  const [refreshing, setRefreshing] = useState(false);

  const getData = useCallback(
    async (refreshFlag?: boolean) => {
      if (refreshFlag) {
        setRefreshing(true);
      }
      try {
        const result = await api();
        setInit(true);
        setData(result);
        if (result.length >= 10) {
          setCanAppend(true);
        } else {
          setAppendIng(false);
        }
        if (refreshFlag) {
          setRefreshing(false);
        }
      } catch (error) {
        ToastManger.displayAlert({
          // @ts-ignore
          message: error?.cnmsg || '网络连接超时，请点击重试 或切换网络重试。',
        });
      }
    },
    [api],
  );

  const appendData = useCallback(async () => {
    if (canAppend) {
      setAppendIng(true);
      try {
        const extraData = await api(data?.length);
        const total = data?.concat(extraData);
        setData(total);
        if (extraData.length >= 10) {
          setCanAppend(true);
        } else {
          setCanAppend(false);
        }
      } catch (error) {
        ToastManger.displayAlert({
          // @ts-ignore
          message: error?.cnmsg || '网络连接超时，请点击重试 或切换网络重试。',
        });
      }
    }
    setAppendIng(false);
  }, [api, canAppend, data]);

  useEffect(() => {
    getData();
  }, [getData]);

  const onRefresh = useCallback(() => {
    getData(true);
  }, [getData]);

  return (
    <BGList
      data={data}
      renderItem={renderItem}
      refreshControl={
        <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
      }
      style={{flex: 1}}
      onEndReached={appendData}
      ListEmptyComponent={init ? <Empty /> : undefined}
      ListFooterComponent={
        !!data?.length ? (
          appending ? (
            <ActivityIndicator />
          ) : !canAppend ? (
            <Text style={{textAlign: 'center'}}>到底了</Text>
          ) : (
            <Text style={{textAlign: 'center', color: STYLE_COLOR.TEXT_GREY}}>
              上拉加载更多数据
            </Text>
          )
        ) : undefined
      }
      ListHeaderComponent={ListHeaderComponent}
    />
  );
}
